/*******************************************************\
|* Author: Trevor Sundberg
\*******************************************************/

// Header protection
#pragma once
#ifndef SKUGO_DEBUG_HPP
#define SKUGO_DEBUG_HPP

// As long as this isn't a final build...
#if !defined(FINAL)

  // If this is a Microsoft compiler...
  #if defined(_MSC_VER)
    // Use the intrinsic debug break functionality
    #define SkugoHardBreak __debugbreak()
    #define SkugoSoftBreak __debugbreak()
  #else
    // Otherwise, just use standard assert functionality
    #include <cassert>
    #define SkugoHardBreak assert(false)
    #define SkugoSoftBreak
  #endif

#else
  // When we're in final mode, break points do nothing
  #define SkugoHardBreak
  #define SkugoSoftBreak
#endif

// If this is a Microsoft compiler (2010 or later)...
#if _MSC_VER >= 1600
  // Use the latest 0x additions for static asserts
  #define SkugoStaticAssert(condition, reason) static_assert(condition, reason)
#else
  // We could use other tricks for static asserts, but they are a lot less
  // clear in terms of errors. For now, just do nothing since asserts aren't crutial
  #define SkugoStaticAssert(condition, reason) void SkugoStaticAssertX(char[int(bool(condition)) * 2 - 1]);
#endif

// Raise a warning
#define SkugoWarning(reason) SkugoSoftBreak;

// Raise an error immediately with no condition
#define SkugoError(reason) SkugoHardBreak;

// Raise an error if a condition is met
#define SkugoErrorIf(value, reason) if (value) { SkugoHardBreak; }

// Raise an error and then immediately return if a condition is met
#define SkugoReturnIf(value, valueToReturn, reason)  if (value) { SkugoHardBreak; return valueToReturn; }

// End header protection
#endif
